package com.xd.demo.aspect;




import com.xd.demo.dto.JdResDto;
import com.xd.demo.process.impl.ReqResProcessorJdImpl;
import com.xd.demo.util.AesUtils;
import jdk.nashorn.internal.runtime.regexp.joni.constants.OPCode;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class CryptoAspect {
   private JdResDto jdResDto;

    // 切入点
    @Pointcut("@annotation(com.xd.demo.aspect.CryptoAnnotation)")
    private void CryptoPointCut(){}

    @Value("${jd.slat}")
    private String salt;

    @Value("${jd.key}")
    private String key;

    private Logger logger = LoggerFactory.getLogger(CryptoAspect.class);

    // 使用aop 做 加密签名处理
    // 使用拦截器 做 解密验签处理


    @Around("CryptoPointCut()")
    public Object arrount(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        logger.debug(String.format("加解密切面执行:%s", method.getName()));
        CryptoAnnotation annotation = method.getAnnotation(CryptoAnnotation.class);
        String model = annotation.model();// JD 或者 Xiaomi
        String operation = annotation.operation();
        try{
            Object result = point.proceed();
            // 通过判断 进行 类型转化，参数加密加签
            if(model.equals("JD") && operation.equals("jd_credit")){
                jdResDto = (JdResDto)result;
                String encryptAES = AesUtils.encryptAES(key, jdResDto.getResponseData());
                String sign = AesUtils.sign(encryptAES, salt);
                jdResDto.setResponseData(encryptAES);
                jdResDto.setSysSign(sign);
            }
        }catch (Exception e){
            // 如何判断异常种类呢？抛出特定的异常，在这处理；
            // 自定义异常，判断异常类型
        }finally {

        }
        return jdResDto;
    }






}
